package org.finesys.common.netty.websocket.wrapper;

import io.netty.channel.Channel;
import io.netty.handler.codec.http.QueryStringDecoder;
import org.finesys.common.netty.websocket.support.WsPathMatcher;
import org.springframework.util.AntPathMatcher;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

import static org.finesys.common.netty.websocket.constants.WebSocketAttributeKeyConstants.URI_TEMPLATE;


public class AntPathMatcherWrapper extends AntPathMatcher implements WsPathMatcher {

    private final String pattern;

    /**
     * AntPathMatcherWrapper的构造函数。
     *
     * @param pattern 需要匹配的路径模式字符串。
     */
    public AntPathMatcherWrapper(String pattern) {
        this.pattern = pattern;
    }

    /**
     * 获取当前AntPathMatcherWrapper对象的路径模式。
     *
     * @return 返回当前AntPathMatcherWrapper对象的路径模式字符串。
     */
    @Override
    public String getPattern() {
        return this.pattern;
    }

    /**
     * 重写matchAndExtract方法，用于判断并提取查询字符串中的特定参数。
     *
     * @param decoder 包含查询字符串的解码器对象
     * @param channel 对应的通道对象
     * @return 如果匹配成功并成功提取参数，则返回true；否则返回false
     */
    @Override
    public boolean matchAndExtract(QueryStringDecoder decoder, Channel channel) {
        // 创建一个LinkedHashMap来存储变量
        Map<String, String> variables = new LinkedHashMap<>();
        // 调用doMatch方法进行路径匹配，并将匹配的变量存储在variables中
        boolean result = doMatch(pattern, decoder.path(), true, variables);
        if (result) {
            // 如果匹配成功，将变量存储在channel的URI_TEMPLATE属性中
            channel.attr(URI_TEMPLATE).set(variables);
            return true;
        }
        return false;
    }


    /**
     * 重写hashCode方法，用于返回当前对象的哈希码。
     *
     * @return 返回当前对象的哈希码。
     */
    @Override
    public int hashCode() {
        return Objects.hash(pattern);
    }

    /**
     * 重写equals方法，用于比较两个AntPathMatcherWrapper对象是否相等。
     *
     * @param obj 要比较的对象
     * @return 如果当前对象与obj相等，则返回true；否则返回false
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        AntPathMatcherWrapper that = (AntPathMatcherWrapper) obj;
        return Objects.equals(pattern, that.pattern);
    }
}
